#include "stdafx.h"
#include "05ObjModelRender.h"

#define MAX_LOADSTRING 100

//  应用到本示例程序中的常量buffer
// 要使用16位对齐，否则创建cb的时候会出问题
__declspec(align(16)) struct PerFrameConstBufferParam
{
	H3DMatrix		WVP;
	H3DMatrix		world;
	H3DVector4		diffuse_color;
	bool			has_texture;
};

__declspec(align(16)) struct LightConstBufferParam
{
	H3DLight light;
};

PerFrameConstBufferParam		perframe_cb_param;
HINSTANCE						instance_handle;								// current instance
TCHAR							title[MAX_LOADSTRING];			// The title bar text
TCHAR							window_class[MAX_LOADSTRING];		// the main window class name
HWND							wnd_handle = NULL;
H3DVertexBuffer*				model_vbuffer = 0;					// obj模型的vb
H3DIndexBuffer*					model_ibuffer = 0;					// obj模型的ib
H3DVertexShader*				model_vs = 0;						// 渲染obj模型所使用的vs
H3DPixelShader*					model_ps = 0;						// 渲染obj模型所使用的ps
H3DObjModelVertex*				model_vertex_array = 0;
H3DObjModelLoader*				model_loader = 0;
H3DConstantBuffer*				model_const_buff = 0;
H3DConstantBuffer*				light_const_buff = 0;
PerFrameConstBufferParam		model_cb_param;
H3DCamera*						camera = NULL;
LightConstBufferParam			light_cb_param;
vector<H3DTexture*>				textures;
H3DSingleRenderTargetBlendState blend_state;
H3DRasterizerState				rasterizer_state;
H3DSamplerState					sampler_state;
H3DDepthStencilState			depth_stencil_state;

ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
void				Render();
void				InitGeometry();
void				Shutdown();
void				OnKeyDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
	MSG msg;
	LoadString(hInstance, IDS_APP_TITLE, title, MAX_LOADSTRING);
	LoadString(hInstance, IDC_MY05OBJMODELRENDER, window_class, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	memset(&msg,0,sizeof(msg));

	while( msg.message != WM_QUIT )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{ 
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			Render();
		}
	}

	Shutdown();
	return (int) msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX winClass;
	winClass.lpszClassName = _T("MY_WINDOWS_CLASS");
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc   = WndProc;
	winClass.hInstance     = hInstance;
	winClass.hIcon	       = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
	winClass.hIconSm	   = LoadIcon(hInstance, (LPCTSTR)IDI_APPLICATION);
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;
	return RegisterClassEx(&winClass);	
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   instance_handle = hInstance; 

   wnd_handle = CreateWindowEx( NULL, _T("MY_WINDOWS_CLASS"), 
	   _T("Heaven 3D Framework based on DX11 - 05ObjModelRender"),
	   WS_OVERLAPPEDWINDOW | WS_VISIBLE,
	   0, 0, 640, 480, NULL, NULL, hInstance, NULL );

   if (!wnd_handle)
   {
      return FALSE;
   }

   ShowWindow(wnd_handle, nCmdShow);
   UpdateWindow(wnd_handle);
   InitGeometry();
   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		OnKeyDown(hWnd,message,wParam,lParam);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

void Render()
{
	H3DRenderer::GetSingletonPtr()->BeginScene(0.0f, 0.125f, 0.3f, 1.0f);

	ID3D11Device* device = H3DRenderer::GetSingletonPtr()->GetDevice();
	ID3D11DeviceContext* device_context = H3DRenderer::GetSingletonPtr()->GetDeviceContext();

	camera->Update();

	model_vs->Set();
	model_ps->Set();

	H3DMatrix mesh_world;
	H3DMatrix tmp_rotation;
	H3DMatrix tmp_scale;
	H3DMatrix tmp_translation;

	static float rot_angle = 0.f;
	rot_angle++;

	mesh_world.Identity();
	tmp_rotation.RotationY(rot_angle);
	tmp_scale.Scaling(1.f,1.f,1.f);
	tmp_translation.Translation(0.f,0.f,0.f);

	mesh_world = tmp_rotation * tmp_scale * tmp_translation; // 计算 

	const vector<H3DObjModelMaterial>& mesh_materials = model_loader->GetMaterials();
	const vector<int32_t>& mesh_sub_mtl_array = model_loader->GetSubsetMaterialArray();
	const vector<int32_t>& subset_index_start = model_loader->GetSubsetIndexStart();

	blend_state.Set(); // 设置混合状态
	rasterizer_state.Apply();	// 设置光栅器状态
	sampler_state.Set();
	depth_stencil_state.Apply();

	light_const_buff->SetStartSlot(0);
	model_const_buff->SetForPixelShader();

	int32_t subset_count = model_loader->GetSubsetCount();

	/*for(int32_t i = 0; i < subset_count; ++i )
	{*/
		model_ibuffer->Set();
		model_vbuffer->Set();

		// 设置constant buffer 所需要的各种参数
		model_cb_param.world = mesh_world;
		model_cb_param.world.Transpose();
		model_cb_param.WVP = mesh_world * camera->GetViewMatrix() * camera->GetPerspectiveMatrix();
		model_cb_param.WVP.Transpose();
		model_cb_param.diffuse_color = H3DVector4(1.f,1.f,1.f,1.f);//mesh_materials[mesh_sub_mtl_array[i]].diffuse_color_;
		model_cb_param.has_texture = true;//mesh_materials[mesh_sub_mtl_array[i]].has_texture_;

		model_const_buff->UpdateSubresource(&model_cb_param); // 常量缓冲区中的参数发生变化了，更新之
		model_const_buff->SetStartSlot(0);
		model_const_buff->SetForVertexShader(); // 把常量缓冲区设置给vertex shader
		model_const_buff->SetStartSlot(1);
		model_const_buff->SetForPixelShader(); // 把常量缓冲区设置给pixel shader，start slot要设为1

		//if( mesh_materials[mesh_sub_mtl_array[i]].has_texture_  ) // 如果本材质使用了纹理则启用纹理
		//{
			uint32_t texture_index = 0;//(uint32_t)mesh_materials[mesh_sub_mtl_array[i]].texture_array_index_;
			textures[texture_index]->SetResourcesForPixelShader();
		/*}*/

		// 接下来要设置拣选模式和纹理采样方式
		int32_t index_start = 0;//subset_index_start[i];
		int32_t index_draw_count = model_ibuffer->GetIndexCount();//subset_index_start[i+1] - subset_index_start[i];

		/*if( mesh_materials[mesh_sub_mtl_array[i]].transparent_ == false )
		{*/
			device_context->DrawIndexed( index_draw_count, index_start, 0 );
		/*}*/
	/*}*/

	//H3DDepthStencilState::ZeroClearing();

	H3DRenderer::GetSingletonPtr()->EndScene();
}

void InitGeometry()
{
	H3DRenderer::GetSingletonPtr()->Initialize( 640 , 480 , true , wnd_handle , false , 1000.f,-30.f );
//===================
	model_loader = new H3DObjModelLoader;
	bool ret = model_loader->LoadFromFile(_T("spaceCompound.obj"));

	if( !ret )
	{
		MessageBox(wnd_handle,_T("load spaceCompound.obj file error"), _T("Error"), MB_OK );
		return;
	}
//===================
	H3DVector2 tex_coord;
	H3DVector3 normal;

	/*{ vertices[0].pos = H3DVector3( -10.0f, 10.0f, -10.0f ); vertices[0].tex_coord = H3DVector2( 0.0f, 0.0f);vertices[0].normal =H3DVector3(0.f,0.f,-1.f); };
	{ vertices[1].pos = H3DVector3( 10.0f, 10.0f, -10.0f );vertices[1].tex_coord = H3DVector2( 0.0f, 1.0f );vertices[1].normal =H3DVector3(0.f,0.f,-1.f); };
	{ vertices[2].pos =  H3DVector3( 10.0f, 10.0f, 10.0f ); vertices[2].tex_coord = H3DVector2( 0.0f, 1.0f );vertices[2].normal =H3DVector3(0.f,0.f,-1.f); };
	{ vertices[3].pos = H3DVector3( -10.0f, 10.0f, 10.0f ); vertices[3].tex_coord = H3DVector2( 1.0f, 0.0f );vertices[3].normal =H3DVector3(0.f,0.f,-1.f);};
	{ vertices[4].pos = H3DVector3( -10.0f, -10.0f, -10.0f );vertices[4].tex_coord =  H3DVector2( 1.0f, 0.0f );vertices[4].normal =H3DVector3(0.f,0.f,-1.f);};
	{ vertices[5].pos =  H3DVector3( 10.0f, -10.0f, -10.0f ); vertices[5].tex_coord = H3DVector2( 1.0f, 1.0f );vertices[5].normal =H3DVector3(0.f,0.f,-1.f); };
	{ vertices[6].pos =  H3DVector3( 10.0f, -10.0f, 10.0f ); vertices[6].tex_coord = H3DVector2( 1.0f, 1.0f );vertices[6].normal =H3DVector3(0.f,0.f,-1.f); };
	{ vertices[7].pos =  H3DVector3( -10.0f, -10.0f, 10.0f ); vertices[7].tex_coord = H3DVector2( 0.0f, 0.0f );vertices[7].normal =H3DVector3(0.f,0.f,-1.f);};*/


	//Create the vertex buffer
	H3DObjModelVertex vertices[24] =
	{
		// Front Face
		H3DObjModelVertex(-1.0f, -1.0f, -1.0f, 0.0f, 1.0f,-1.0f, -1.0f, -1.0f),
		H3DObjModelVertex(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f,-1.0f,  1.0f, -1.0f),
		H3DObjModelVertex( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 1.0f,  1.0f, -1.0f),
		H3DObjModelVertex( 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f),

		// Back Face
		H3DObjModelVertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f),
		H3DObjModelVertex( 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f),
		H3DObjModelVertex( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f,  1.0f, 1.0f),
		H3DObjModelVertex(-1.0f,  1.0f, 1.0f, 1.0f, 0.0f,-1.0f,  1.0f, 1.0f),

		// Top Face
		H3DObjModelVertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f,-1.0f, 1.0f, -1.0f),
		H3DObjModelVertex(-1.0f, 1.0f,  1.0f, 0.0f, 0.0f,-1.0f, 1.0f,  1.0f),
		H3DObjModelVertex( 1.0f, 1.0f,  1.0f, 1.0f, 0.0f, 1.0f, 1.0f,  1.0f),
		H3DObjModelVertex( 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f),

		// Bottom Face
		H3DObjModelVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f,-1.0f, -1.0f, -1.0f),
		H3DObjModelVertex( 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f),
		H3DObjModelVertex( 1.0f, -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, -1.0f,  1.0f),
		H3DObjModelVertex(-1.0f, -1.0f,  1.0f, 1.0f, 0.0f,-1.0f, -1.0f,  1.0f),

		// Left Face
		H3DObjModelVertex(-1.0f, -1.0f,  1.0f, 0.0f, 1.0f,-1.0f, -1.0f,  1.0f),
		H3DObjModelVertex(-1.0f,  1.0f,  1.0f, 0.0f, 0.0f,-1.0f,  1.0f,  1.0f),
		H3DObjModelVertex(-1.0f,  1.0f, -1.0f, 1.0f, 0.0f,-1.0f,  1.0f, -1.0f),
		H3DObjModelVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f,-1.0f, -1.0f, -1.0f),

		// Right Face
		H3DObjModelVertex( 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f),
		H3DObjModelVertex( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 1.0f,  1.0f, -1.0f),
		H3DObjModelVertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 1.0f,  1.0f,  1.0f),
		H3DObjModelVertex( 1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, -1.0f,  1.0f),
	};


	model_vbuffer = new H3DVertexBuffer;
	const void* vertex_data = vertices;
	model_vbuffer->Create( 24 , sizeof(H3DObjModelVertex) , 0 , D3D11_USAGE_DEFAULT 
		, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST , vertex_data );
	
	/*model_vbuffer = new H3DVertexBuffer;
	const void* vertex_data = &(model_loader->GetVertices()[0]);
	ret = model_vbuffer->Create( model_loader->GetVertexCount() , sizeof(H3DObjModelVertex), 
		0 , D3D11_USAGE_DEFAULT ,  D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST , vertex_data);*/

	if( !ret )
	{
		MessageBox(wnd_handle,_T("create vertex buffer error"), _T("Error"), MB_OK );
		return;
	}
	
//===================
	// == 创建索引缓冲

	uint32_t indices[] = {
		// Front Face
		0,  1,  2,
		0,  2,  3,

		// Back Face
		4,  5,  6,
		4,  6,  7,

		// Top Face
		8,  9, 10,
		8, 10, 11,

		// Bottom Face
		12, 13, 14,
		12, 14, 15,

		// Left Face
		16, 17, 18,
		16, 18, 19,

		// Right Face
		20, 21, 22,
		20, 22, 23
	};


	model_ibuffer = new H3DIndexBuffer;
	const uint32_t* index_data = indices;
	ret = model_ibuffer->Create(  36 , index_data );
	/*
	model_ibuffer = new H3DIndexBuffer;
	const uint32_t* index_data = &(model_loader->GetIndices()[0]);
	ret = model_ibuffer->Create( model_loader->GetIndexCount() , index_data );

	if( !ret )
	{
		MessageBox(wnd_handle,_T("create index buffer error"), _T("Error"), MB_OK );
		return;
	}
	*/
//================== // 创建纹理图
	const vector<H3DString>& texture_name_array = model_loader->GetTextureNameArray();

	for( size_t i = 0 ; i < texture_name_array.size() ; ++i )
	{
		H3DSourceTexture* src_texture = new H3DSourceTexture();
		bool ret = src_texture->CreateFromFile( texture_name_array[i].c_str() );

		if( ret )
			textures.push_back(src_texture);
	}
	//textures[texture_index]
//===================
	camera = new H3DCamera;
	/*
	
	camera->SetLookAt( H3DVector3(0.0f, 0.0f, -10.0f) , H3DVector3( 0.0f, 0.0f, 0.0f) , H3DVector3(0.0f, 1.0f, 0.0f) );
	camera->SetPerspectiveLH( 0.4f*3.14f, 640.f/480.f, 0.f, 1000.0f );
	camera->Update();
*/
	H3DVector3 eye = H3DVector3( 0.0f, 0.0f, -5.0f );
	H3DVector3 at = H3DVector3( 0.0f, 1.0f, 0.0f);
	H3DVector3 up = H3DVector3( 0.0f, 1.0f, 0.0f);
	camera->SetPerspectiveLH(  XM_PIDIV2, 640.f / 480.f, 0.1f, 100.0f );
	//g_proj_mat.PerspectiveFovLH( XM_PIDIV2, 640.f / 480.f, 0.1f, 100.0f);
	//g_view_mat.LookAtLH( eye , at , up );

	camera->SetLookAt(eye,at,up);
	camera->Update();
//===================
	D3D11_INPUT_ELEMENT_DESC polygonLayout[3];
	polygonLayout[0].SemanticName = "POSITION";
	polygonLayout[0].SemanticIndex = 0;
	polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[0].InputSlot = 0;
	polygonLayout[0].AlignedByteOffset = 0;
	polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[0].InstanceDataStepRate = 0;

	polygonLayout[1].SemanticName = "TEXCOORD";
	polygonLayout[1].SemanticIndex = 0;
	polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;
	polygonLayout[1].InputSlot = 0;
	polygonLayout[1].AlignedByteOffset = 12;
	polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[1].InstanceDataStepRate = 0;

	polygonLayout[2].SemanticName = "NORMAL";
	polygonLayout[2].SemanticIndex = 0;
	polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
	polygonLayout[2].InputSlot = 0;
	polygonLayout[2].AlignedByteOffset = 20;
	polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	polygonLayout[2].InstanceDataStepRate = 0;

	uint32_t num_elem = sizeof(polygonLayout) / sizeof(polygonLayout[0]);
	model_vs = new H3DVertexShader;
	model_vs->Create(_T("05_obj_model_render_effects.fx"),_T("VS"), _T("vs_4_0"),polygonLayout , num_elem );
//===================
	model_ps = new H3DPixelShader;
	model_ps->Create(_T("05_obj_model_render_effects.fx"),_T("PS"), _T("ps_4_0"));

//=================== 创建每帧都要用到的cb参数
	H3DMatrix mesh_world;
	mesh_world.Identity();

	H3DMatrix tmp_rotation;
	tmp_rotation.RotationY(3.14f);

	H3DMatrix tmp_scale;
	tmp_scale.Scaling(1.f,1.f,1.f);

	H3DMatrix tmp_translation;
	tmp_translation.Translation(0.f,0.f,0.f);

	mesh_world = tmp_rotation * tmp_scale * tmp_translation;

	model_cb_param.world = mesh_world;
	model_cb_param.world.Transpose();
	model_cb_param.WVP = mesh_world * camera->GetViewMatrix() * camera->GetPerspectiveMatrix();
	model_cb_param.WVP.Transpose();
	model_cb_param.diffuse_color = H3DVector4(1.f,1.f,1.f,1.f);
	model_cb_param.has_texture = true;
	model_const_buff = new H3DConstantBuffer; //  生成给shader传递的常量buffer
	model_const_buff->Create( &model_cb_param , sizeof(PerFrameConstBufferParam) , D3D11_USAGE_DYNAMIC );

//=====================创建一个混合状态
	blend_state.Create(true,D3D11_BLEND_INV_SRC_ALPHA,D3D11_BLEND_SRC_ALPHA,D3D11_BLEND_OP_ADD
		,D3D11_BLEND_INV_SRC_ALPHA,D3D11_BLEND_SRC_ALPHA,D3D11_BLEND_OP_ADD,D3D10_COLOR_WRITE_ENABLE_ALL);
//=====================创建一个采样状态
	sampler_state.Create( D3D11_FILTER_MIN_MAG_MIP_LINEAR ,D3D11_TEXTURE_ADDRESS_WRAP , 
		D3D11_TEXTURE_ADDRESS_WRAP , D3D11_TEXTURE_ADDRESS_WRAP , 
		0.f , 1 ,D3D11_COMPARISON_NEVER);
//=====================创建一个深度模板缓冲区状态
	//depth_stencil_state.Create(true,D3D11_DEPTH_WRITE_MASK_ALL,D3D11_COMPARISON_LESS_EQUAL);
//=====================创建一个rasterizer
	rasterizer_state.Create(D3D11_FILL_SOLID,D3D11_CULL_NONE,true);

//=====================  创建灯光const buffer参数
	light_cb_param.light.SetPosition( 0.0f, 1.0f, -100.0f);
	light_cb_param.light.SetDirection(0.0f, 0.0f, 1.0f);
	light_cb_param.light.SetRange(1000.0f);
	light_cb_param.light.SetCone(20.0f);
	light_cb_param.light.SetAttenuation(0.f);
	light_cb_param.light.SetAmbientColor(0.2f, 0.2f, 0.2f, 1.0f);
	light_cb_param.light.SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);

	H3DVector3 light_pos = camera->GetPos();
	light_cb_param.light.SetPosition(light_pos.x,light_pos.y,light_pos.z );
	
	light_const_buff = new H3DConstantBuffer;
	light_const_buff->Create( &light_cb_param , sizeof(LightConstBufferParam) , D3D11_USAGE_DYNAMIC );
}

void Shutdown()
{
	H3D_SAFE_DELETE(model_vbuffer);
	H3D_SAFE_DELETE(model_ibuffer);
	H3D_SAFE_DELETE(model_loader);
	H3D_SAFE_DELETE(model_vs);
	H3D_SAFE_DELETE(model_ps);
	H3D_SAFE_DELETE(light_const_buff);
	H3D_SAFE_DELETE(model_const_buff);
}

void OnKeyDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	H3DVector3 camera_pos;
	float move_speed = 1.f;
	char pos_disp[256];

	switch(wParam)
	{
	case VK_UP:
		camera_pos = camera->GetPos();
		camera_pos.z += move_speed;
		camera->SetPos(camera_pos);
		break;
	case VK_DOWN:
		camera_pos = camera->GetPos();
		camera_pos.z -= move_speed;
		camera->SetPos(camera_pos);
		break;
	case VK_LEFT:
		camera_pos = camera->GetPos();
		camera_pos.x -= move_speed;
		camera->SetPos(camera_pos);
		break;
	case VK_RIGHT:
		camera_pos = camera->GetPos();
		camera_pos.x += move_speed;
		camera->SetPos(camera_pos);
		break;
	}

	memset(pos_disp,0,sizeof(char)*256);
	sprintf(pos_disp,"cam pos = (%f , %f , %f )\n" , camera_pos.x , camera_pos.y ,camera_pos.z );
	OutputDebugString(pos_disp);
}